package nc.impl.so.m4331;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import nc.bs.so.m4331.maintain.QueryDeliveryBP;
import nc.impl.pubapp.bill.convertor.BillToViewConvertor;
import nc.impl.pubapp.bill.convertor.ViewToBillConvertor;
import nc.impl.pubapp.pattern.data.view.SchemeViewQuery;
import nc.impl.pubapp.pattern.data.view.ViewQuery;
import nc.impl.pubapp.pattern.data.vo.VOQuery;
import nc.impl.pubapp.pattern.database.DataAccessUtils;
import nc.impl.pubapp.pattern.database.IDExQueryBuilder;
import nc.impl.pubapp.pattern.pub.LockOperator;
import nc.impl.so.m4331.action.maintain.DeliveryDeleteAction;
import nc.impl.so.m4331.action.maintain.DeliveryInsertAction;
import nc.impl.so.m4331.action.maintain.DeliveryPushWriteAction;
import nc.impl.so.m4331.action.maintain.DeliveryUpdateAction;
import nc.itf.so.m4331.IDeliveryMaintain;
import nc.pubitf.so.m4331.pub.VOCombinUtil;
import nc.ui.querytemplate.querytree.IQueryScheme;
import nc.vo.ml.NCLangRes4VoTransl;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFBoolean;
import nc.vo.pubapp.pattern.data.IRowSet;
import nc.vo.pubapp.pattern.exception.ExceptionUtils;
import nc.vo.pubapp.pattern.pub.SqlBuilder;
import nc.vo.pubapp.query2.sql.process.QuerySchemeProcessor;
import nc.vo.scmpub.res.billtype.SOBillType;
import nc.vo.scmpub.res.billtype.TOBillType;
import nc.vo.scmpub.util.AppendSCCTSqlUtil;
import nc.vo.scmpub.util.CombineViewToAggUtil;
import nc.vo.scmpub.util.ValueCheckUtil;
import nc.vo.so.m4331.entity.DeliveryBVO;
import nc.vo.so.m4331.entity.DeliveryHVO;
import nc.vo.so.m4331.entity.DeliveryVO;
import nc.vo.so.m4331.entity.DeliveryViewVO;
import nc.vo.so.pub.SOParameterVO;
import nc.vo.so.pub.SOTable;
import nc.vo.so.pub.comparator.RowNoComparator;
import nc.vo.so.pub.enumeration.BillStatus;
import nc.vo.so.pub.query.SOQuerySchemeUtils;









public class DeliveryMaintainImpl
  implements IDeliveryMaintain
{
  private void appendFixedWhr(IQueryScheme qs, QuerySchemeProcessor qsp) {
    String halias = qsp.getMainTableAlias();
    SqlBuilder whr = new SqlBuilder();

    
    Object obusi = qs.get("cbiztypeid");
    String[] sbusi = null;
    if (obusi != null) {
      sbusi = (String[])obusi;
      whr.append(" and (");
      IDExQueryBuilder iq = new IDExQueryBuilder(SOTable.TMP_SO_ID1.getName());
      whr.append(iq.buildSQL(halias + "." + "cbiztypeid", sbusi));
      whr.append(") ");
    } 
    
    Object otrantype = qs.get("vtrantypecode");
    String[] strantype = null;
    if (otrantype != null) {
      strantype = (String[])otrantype;
      whr.append(" and (");
      IDExQueryBuilder iq = new IDExQueryBuilder(SOTable.TMP_SO_ID2.getName());
      whr.append(iq.buildSQL(halias + "." + "vtrantypecode", strantype));
      whr.append(") ");
    } 

    
    int[] fstaus = { BillStatus.AUDIT.getIntValue(), BillStatus.CLOSED.getIntValue() };

    
    whr.append(" and (");
    whr.append(halias);
    whr.append(".");
    whr.append("fstatusflag", fstaus);
    whr.append(") ");
    
    qsp.appendWhere(whr.toString());
  }



  
  public DeliveryVO[] approveDelivery(DeliveryVO[] vos) throws BusinessException { return null; }








  
  private String createOrderSql(IQueryScheme queryScheme) {
    SqlBuilder order = new SqlBuilder();
    QuerySchemeProcessor processor = new QuerySchemeProcessor(queryScheme);
    order.append(" order by ");
    
    String tableName = processor.getTableAliasOfAttribute(DeliveryHVO.class, "vbillcode");
    
    order.append(tableName);
    order.append(".");
    order.append("vbillcode");
    order.append(",");
    
    tableName = processor.getTableAliasOfAttribute(DeliveryBVO.class, "crowno");
    
    order.append(tableName);
    order.append(".");
    order.append("crowno");
    return order.toString();
  }
  
  private void createSqlByQuerySchemeFor4804(IQueryScheme queryScheme) {
    QuerySchemeProcessor qsp = new QuerySchemeProcessor(queryScheme);
    
    appendFixedWhr(queryScheme, qsp);

    
    qsp.appendCurrentGroup();


    
    String subTable = qsp.getTableAliasOfAttribute(DeliveryBVO.class, "bcheckflag");
    
    SqlBuilder where = new SqlBuilder();
    
    where.append(" and (");
    where.append(subTable);
    where.append(".");
    where.append("btransendflag", UFBoolean.FALSE.toString());
    where.append(") ");
    
    where.append(" and isnull(" + subTable + ".nnum,0)-isnull(" + subTable + ".ntotaltransnum,0)");
    
    where.append(" >0 ");

    
    qsp.appendWhere(where.toString());
    
    Object obj = queryScheme.get("SRCBIDSARRAY");
    if (obj != null) {
      String[] srcBids = (String[])obj;
      if (srcBids.length > 0) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendNot(subTable + "." + "cdeliverybid", srcBids);
        qsp.appendWhere(" and ");
        qsp.appendWhere(sql.toString());
      } 
    } 
  }
  
  private void createSqlByQuerySchemeFor4C(IQueryScheme queryScheme) {
    QuerySchemeProcessor qsp = new QuerySchemeProcessor(queryScheme);
    
    (new SOQuerySchemeUtils()).appendFixedWhr(queryScheme, qsp);
    
    AppendSCCTSqlUtil.appendID4scctdv(queryScheme, qsp);
    
    qsp.appendCurrentGroup();


    
    String subTable = qsp.getTableAliasOfAttribute(DeliveryBVO.class, "bcheckflag");
    
    SqlBuilder where = new SqlBuilder();
//    where.append(" and (");
//    where.append(subTable);
//    where.append(".");
//    where.append("vsrctype", SOBillType.Order.getCode());
//    where.append(") ");
    
    where.append(" and (");
    where.append(subTable);
    where.append(".");
    where.append("boutendflag", UFBoolean.FALSE.toString());
    where.append(") ");
    
    where.append(" and abs(isnull(" + subTable + ".nnum,0))-abs(isnull(" + subTable + ".ntotalnotoutnum,0))");
    
    where.append(" >0 ");

    
    qsp.appendWhere(where.toString());
  }







  
  private void createSqlByQuerySchemeFor4Y(IQueryScheme queryScheme) {
    QuerySchemeProcessor qsp = new QuerySchemeProcessor(queryScheme);
    
    (new SOQuerySchemeUtils()).appendFixedWhr(queryScheme, qsp);

    
    qsp.appendCurrentGroup();


    
    String subTable = qsp.getTableAliasOfAttribute(DeliveryBVO.class, "bcheckflag");
    
    SqlBuilder where = new SqlBuilder();
    where.append(" and (");
    where.append(subTable);
    where.append(".");
    where.append("vsrctype", TOBillType.TransOrder.getCode());
    where.append(") ");
    
    where.append(" and (");
    where.append(subTable);
    where.append(".");
    where.append("boutendflag", UFBoolean.FALSE.toString());
    where.append(") ");

    
    where.append(" and abs(isnull(" + subTable + ".nnum,0))-abs(isnull(" + subTable + ".ntotalnotoutnum,0))");
    
    where.append(" >0 ");
    
    where.append(" and abs(isnull(" + subTable + ".nnum,0))-abs(isnull(" + subTable + ".ntotaloutnum,0))");
    
    where.append(" >0 ");
    
    where.append(" and abs(isnull(" + subTable + ".ntotalnotoutnum,0))+abs(isnull(" + subTable + ".ntotaloutnum,0))");
    
    where.append(" < abs(isnull(" + subTable + ".nnum,0))");

    
    qsp.appendWhere(where.toString());
  }








  
  public void deleteDelivery(DeliveryVO[] vos) throws BusinessException {
    try {
      DeliveryDeleteAction action = new DeliveryDeleteAction();
      action.delete(vos);
    }
    catch (Exception e) {
      ExceptionUtils.marsh(e);
    } 
  }


  
  public DeliveryVO[] insertDelivery(DeliveryVO[] insertvos) throws BusinessException {
    DeliveryVO[] ret = null;
    try {
      DeliveryInsertAction action = new DeliveryInsertAction();
      ret = action.insert(insertvos);
    }
    catch (Exception ex) {
      ExceptionUtils.marsh(ex);
    } 
    return ret;
  }

  
  private void lockBid(DeliveryVO[] vos) throws BusinessException {
    if (null == vos) {
      return;
    }
    Set<String> bidSet = new HashSet<String>();
    for (DeliveryVO vo : vos) {
      DeliveryBVO[] bvos = vo.getChildrenVO();
      for (DeliveryBVO bvo : bvos) {
        bidSet.add(bvo.getCdeliverybid());
      }
    } 
    String[] bids = new String[bidSet.size()];
    bidSet.toArray(bids);
    LockOperator lock = new LockOperator();
    lock.lock(bids, 
        
        NCLangRes4VoTransl.getNCLangRes().getStrByID("4006002_0", "04006002-0075"));
  }



  
  public DeliveryVO[] pushWriteDelivery(SOParameterVO paravo) throws BusinessException {
    DeliveryVO[] retvos = null;
    try {
      DeliveryPushWriteAction action = new DeliveryPushWriteAction();
      retvos = action.pushwrite(paravo);
    }
    catch (Exception ex) {
      ExceptionUtils.marsh(ex);
    } 
    return retvos;
  }


  
  public DeliveryVO[] queryDelivery(String sql) throws BusinessException {
    QueryDeliveryBP bp = new QueryDeliveryBP();
    return bp.query(sql);
  }


  
  public DeliveryVO[] queryDelivery(String[] bids) throws BusinessException {
    DeliveryViewVO[] views = (DeliveryViewVO[])(new ViewQuery(DeliveryViewVO.class)).query(bids);
    if (ValueCheckUtil.isNullORZeroLength(views)) {
      return null;
    }
    ViewToBillConvertor viewToBillConvertor = new ViewToBillConvertor(DeliveryVO.class);
    
    return (DeliveryVO[])viewToBillConvertor.convert(views);
  }




  
  public DeliveryViewVO[] queryDeliveryFor4804(IQueryScheme queryScheme) throws BusinessException {
    createSqlByQuerySchemeFor4804(queryScheme);
    
    String ordersql = createOrderSql(queryScheme);
    
    DeliveryVO[] queryVos = null;
    
    queryVos = queryDeliveryVOForSource(queryScheme, ordersql);
    
    if (null == queryVos || queryVos.length == 0) {
      return null;
    }
    BillToViewConvertor billToViewConvertor = new BillToViewConvertor(DeliveryViewVO.class);

    
    return (DeliveryViewVO[])billToViewConvertor.convert(queryVos);
  }



  
  public DeliveryVO[] queryDeliveryFor4C(IQueryScheme queryScheme) throws BusinessException {
    createSqlByQuerySchemeFor4C(queryScheme);
    
    String ordersql = createOrderSql(queryScheme);
    
    DeliveryVO[] queryVos = queryDeliveryVOForSource(queryScheme, ordersql);
    lockBid(queryVos);
    VOCombinUtil combin = new VOCombinUtil();
    return combin.combinTODeliveryvo(queryVos);
  }



  
  public DeliveryVO[] queryDeliveryFor4Y(IQueryScheme queryScheme) throws BusinessException {
    createSqlByQuerySchemeFor4Y(queryScheme);
    
    String ordersql = createOrderSql(queryScheme);
    
    DeliveryVO[] queryVos = queryDeliveryVOForSource(queryScheme, ordersql);
    VOCombinUtil combin = new VOCombinUtil();
    return combin.combinTODeliveryvo(queryVos);
  }







  
  private DeliveryVO[] queryDeliveryVOForSource(IQueryScheme scheme, String order) {
    SchemeViewQuery<DeliveryViewVO> query = new SchemeViewQuery<DeliveryViewVO>(DeliveryViewVO.class);
    
    DeliveryViewVO[] views = (DeliveryViewVO[])query.query(scheme, order);
    if (ValueCheckUtil.isNullORZeroLength(views)) {
      return null;
    }
    Set<String> sethid = new HashSet<String>();
    for (DeliveryViewVO view : views) {
      sethid.add(view.getHead().getCdeliveryid());
    }
    String[] hids = new String[sethid.size()];
    sethid.toArray(hids);
    
    String[] selkeys = { "cdeliveryid", "csenddeptvid", "csenddeptid", "csendemployeeid" };



    
    VOQuery<DeliveryHVO> qrysrv = new VOQuery<DeliveryHVO>(DeliveryHVO.class, selkeys);
    
    DeliveryHVO[] heads = (DeliveryHVO[])qrysrv.query(hids);
    Map<String, DeliveryHVO> maphead = new HashMap<String, DeliveryHVO>();
    for (DeliveryHVO head : heads) {
      maphead.put(head.getCdeliveryid(), head);
    }
    
    for (DeliveryViewVO view : views) {
      DeliveryHVO head = view.getHead();
      DeliveryBVO body = view.getItem();
      
      head.setPk_group(body.getPk_group());
      head.setPk_org(body.getPk_org());
      head.setDbilldate(body.getDbilldate());
    } 

    
    DeliveryVO[] queryVos = (DeliveryVO[])(new CombineViewToAggUtil(DeliveryVO.class, DeliveryHVO.class, DeliveryBVO.class)).combineViewToAgg(views, "cdeliveryid");

    
    for (DeliveryVO vo : queryVos) {
      RowNoComparator c = new RowNoComparator("crowno");
      Arrays.sort(vo.getChildrenVO(), c);
    } 
    return queryVos;
  }




















  
  public DeliveryViewVO[] queryViewVO(String sql) throws BusinessException {
    DataAccessUtils utils = new DataAccessUtils();
    IRowSet rowset = utils.query(sql);
    if (rowset.size() == 0) {
      return new DeliveryViewVO[0];
    }
    String[] ids = rowset.toOneDimensionStringArray();
    ViewQuery<DeliveryViewVO> query = new ViewQuery<DeliveryViewVO>(DeliveryViewVO.class);
    
    return (DeliveryViewVO[])query.query(ids);
  }



  
  public DeliveryVO[] unapproveDelivery(DeliveryVO[] vos) throws BusinessException { return null; }



  
  public DeliveryVO[] updateDelivery(DeliveryVO[] updatevos, DeliveryVO[] originBills) throws BusinessException {
    DeliveryVO[] ret = null;
    try {
      DeliveryUpdateAction action = new DeliveryUpdateAction();
      ret = action.update(updatevos, originBills);
    }
    catch (Exception ex) {
      ExceptionUtils.marsh(ex);
    } 
    return ret;
  }
}
